﻿using LuaInterface;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using YanhuaMMO;

public class ToolsCommons
{
    private Camera CameraMain;
    private Dictionary<String, GameObject> cache;

    private static LuaTable globalConst;
    private static LuaTable soundConst;

    private static ToolsCommons uniqueInstance;
    private ObjectPoolManager objectPool;
    // 定义一个标识确保线程同步
    private static readonly object locker = new object();

    // 定义私有构造函数，使外界不能创建该类实例
    private ToolsCommons()
    {
        cache = new Dictionary<string, GameObject>();
    }

    /// <summary>
    /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
    /// </summary>
    /// <returns></returns>
    public static ToolsCommons GetInstance()
    {
        // 当第一个线程运行到这里时，此时会对locker对象 "加锁"，
        // 当第二个线程运行该方法时，首先检测到locker对象为"加锁"状态，该线程就会挂起等待第一个线程解锁
        // lock语句运行完之后（即线程运行完之后）会对该对象"解锁"
        // 双重锁定只需要一句判断就可以了
        if (uniqueInstance == null)
        {
            lock (locker)
            {
                // 如果类的实例不存在则创建，否则直接返回
                if (uniqueInstance == null)
                {
                    uniqueInstance = new ToolsCommons();
                }
            }
        }
        return uniqueInstance;
    }

    /// <summary>
    /// 等待duration秒
    /// </summary>
    /// <param name="duration"></param>
    /// <returns></returns>
    public static IEnumerator Wait(float duration)
    {
        //Time.deltaTime完成一帧的秒数
        for (float timer = 0; timer < duration; timer += Time.deltaTime)
            yield return 0;
    }

  
    /// <summary>
    /// 获取战斗场景摄像机
    /// </summary>
    /// <returns></returns>
    public Camera GetMainCamera()
    {
        if(null== CameraMain)
        {
            GameObject camera = GameObject.Find("CameraMain");
            if (camera == null || !camera.activeSelf)
                return null;
            CameraMain = camera.GetComponent<Camera>();
        }
        return CameraMain;
    }


    /// <summary>
    /// 返回指定图层的一条寻路
    /// </summary>
    /// <param name="src"></param>
    /// <param name="dist"></param>
    /// <param name="areaMask"></param>
    /// <returns></returns>
    public static UnityEngine.AI.NavMeshPath FindPath(Vector3 src, Vector3 dist, int areaMask)
    {
        UnityEngine.AI.NavMeshPath path = new UnityEngine.AI.NavMeshPath();
        UnityEngine.AI.NavMesh.CalculatePath(src, dist, areaMask, path);
        return path;
    }

    public static UnityEngine.AI.NavMeshPath FindPath(Vector3 src, Vector3 dist)
    {

        return ToolsCommons.FindPath(src, dist, UnityEngine.AI.NavMesh.AllAreas);
    }

    /// <summary>
    /// 判断角色到达目标点
    /// </summary>
    /// <param name="role"></param>
    /// <param name="distination"></param>
    /// <returns></returns>
    public static bool IsArrivedPosition(GameObject role, Vector3 distination)
    {
        return Vector3.Distance(role.transform.position, distination) < 0.05f;
    }

    /// <summary>
    /// 角色属于怪物
    /// </summary>
    /// <param name="role"></param>
    /// <returns></returns>
    public static bool IsMonster(GameObject role)
    {
        return role.tag.StartsWith("Monster");
    }

    /// <summary>
    /// 角色属于玩家或者佣兵
    /// </summary>
    /// <param name="role"></param>
    /// <returns></returns>
    public static bool IsPlayer(GameObject role)
    {
        return role.tag.StartsWith("Player");
    }
    /// <summary>
    /// 判断对象是否属于战斗群体
    /// </summary>
    /// <param name="role"></param>
    /// <returns></returns>
    public static bool IsFightObject(GameObject role)
    {
        return ToolsCommons.IsPlayer(role) || ToolsCommons.IsMonster(role);
    }

    /// <summary>
    /// 判断other是self的队友
    /// </summary>
    /// <param name="self"></param>
    /// <param name="other"></param>
    /// <returns></returns>
    public static bool IsFriend(GameObject self, GameObject other)
    {
        bool result = ToolsCommons.IsFightObject(self) && ToolsCommons.IsFightObject(other);
        result = result && ToolsCommons.IsPlayer(self).Equals(ToolsCommons.IsPlayer(other));
        return result;
    }

    /// <summary>
    /// 非友即敌，这是个错误逻辑
    /// </summary>
    /// <param name="self"></param>
    /// <param name="other"></param>
    /// <returns></returns>
    //public static bool IsEnimy(GameObject self, GameObject other)
    //{
    //    return !ToolsCommons.IsFriend(self, other);
    //}

    public static bool IsEnimy(GameObject self, GameObject other)
    {
        bool result = ToolsCommons.IsFightObject(self) && ToolsCommons.IsFightObject(other);
        result = result && (!(ToolsCommons.IsPlayer(self).Equals(ToolsCommons.IsPlayer(other))));
        return result;
    }

    /// <summary>
    /// 转换服务端点坐标为客户端地图坐标
    /// </summary>
    /// <param name="x"></param>
    /// <param name="z"></param>
    /// <returns></returns>
    public static Vector3 GetMapCoordinate()
    {

        float x = UnityEngine.Random.Range(5.0f, 6.0f);
        if (UnityEngine.Random.Range(0f, 1f) > 0.5)
            x = UnityEngine.Random.Range(-5f, -6f);

        float z = UnityEngine.Random.Range(0f, -8.0f);

        return new Vector3(x, 0, z);

    }

    public static Vector3 GetHeroBornPosition()
    {
        float x = UnityEngine.Random.Range(-0.5f, 0.5f);
        float z = UnityEngine.Random.Range(-1f, -7f);


        return new Vector3(x, 0, z);
    }

   
    /// <summary>
    /// 返回num位于min和max之间,临界值不考虑
    /// </summary>
    /// <param name="min"></param>
    /// <param name="max"></param>
    /// <param name="num"></param>
    /// <returns></returns>
    public static bool IsBetween(float min,float max,float num)
    {
        return num < max && num > min;
    }

 



   


    public static short ChangeMonsterId(short v)
    {
        int n = v / 4 + v * 4 + (v & 0x11);
        if (n > 50) n -= 10;
        if (n < 20) n += 7;
        return (short)n;
    }
    /// <summary>
    /// 获得Global.lua内容
    /// </summary>
    public static string GetGlobalConst(string id,string parameter)
    {
        if(globalConst == null)
        {
            object[] obj = Util.CallMethod("Game", "GetGlobal");
            if (obj != null)
            {
                foreach (var o in obj)
                {
                    globalConst = o as LuaTable;
                    break;
                }
            }
        }
        var table = globalConst.GetTable<LuaTable>(id);
        if(table != null && table[parameter] != null)
        {
            return table[parameter].ToString();
        }
        return null;
    }

    // public static string PlayUISoundByName(string type)
    // {
    //     object[] obj = Util.CallMethod("Game", "PlayUISoundByName", new object[] { type });
    //     if (obj != null)
    //     {
    //         foreach (var o in obj)
    //         {
    //             if (o != null)
    //                 return o.ToString();
    //         }
    //     }
    //     return null;
    // }

    // public static string PlayUISoundByType(string type)
    // {
    //     object[] obj = Util.CallMethod("Game", "PlayUISoundByType", new object[] { type });
    //     if (obj != null)
    //     {
    //         foreach (var o in obj)
    //         {
    //             if (o != null)
    //                 return o.ToString();
    //         }
    //     }
    //     return null;
    // }

    // public static string GetUISoundPath(string name, string para)
    // {
    //     object[] obj = Util.CallMethod("Game", "GetSoundPathByUIName", new object[] { name, para });
    //     if (obj != null)
    //     {
    //         foreach (var o in obj)
    //         {
    //             if(o != null)
    //                 return o.ToString();
    //         }
    //     }
    //     return null;
    // }
    public static int GetMaxVolume(WwiseManager.WwiseFlagEnum flag)
    {
        string _functionName = "";
        switch(flag)
        {
            case WwiseManager.WwiseFlagEnum.Music:
                _functionName = "GetBGVolumeMax";
                break;
            case WwiseManager.WwiseFlagEnum.Sound:
                _functionName = "GetSoundVolumeMax";
                break;
            case WwiseManager.WwiseFlagEnum.Voice:
                _functionName = "GetCVVolumeMax";
                break;
        }
        object[] _objs = Util.CallMethod("Game", _functionName);
        if (_objs != null)
        {
            foreach (var obj in _objs)
            {
                if (obj != null)
                    return int.Parse(obj.ToString());
            }
        }
        return 1;
    }

    //public static int GetBGVolumeMax()
    //{
    //    if (globalConst == null)
    //    {
    //        object[] obj = Util.CallMethod("Game", "GetBGVolumeMax");
    //        if (obj != null)
    //        {
    //            foreach (var o in obj)
    //            {
    //                if (o != null)
    //                    return int.Parse(o.ToString());
    //            }
    //        }
    //    }
    //    return 100;
    //}

    //public static int GetSoundVolumeMax()
    //{
    //    if (globalConst == null)
    //    {
    //        object[] obj = Util.CallMethod("Game", "GetBGVolumeMax");
    //        if (obj != null)
    //        {
    //            foreach (var o in obj)
    //            {
    //                if (o != null)
    //                    return int.Parse(o.ToString());
    //            }
    //        }
    //    }
    //    return 100;
    //}

    //public static int GetCVVolumeMax()
    //{
    //    if (globalConst == null)
    //    {
    //        object[] obj = Util.CallMethod("Game", "GetCVVolumeMax");
    //        if (obj != null)
    //        {
    //            foreach (var o in obj)
    //            {
    //                if (o != null)
    //                    return int.Parse(o.ToString());
    //            }
    //        }
    //    }
    //    return 100;
    //}

    

}
